﻿Friend Class ScanFolder_GroupSubDirectories
    Friend Shared Sub Scan(ByVal tracker As ScanTracker)
        If Not IO.Directory.Exists(tracker.CurrentPath) Then Return

        tracker.ValidPaths.Add(tracker.CurrentPath, Nothing)

        Dim aSubDirs() As String = IO.Directory.GetDirectories(tracker.CurrentPath)

        Dim aSharedItems As Generic.List(Of Entities.SharedItem)
        aSharedItems = DataStore.SharedItems.GetAllBySourceWatchFolderId(tracker.Share.Id)

        'now, remove any item that no longer has an existing subdir
        For i As Integer = aSharedItems.Count - 1 To 0 Step -1
            Dim clsItem As Entities.SharedItem = aSharedItems(0)

            Dim blnRemove As Boolean = True
            For Each strSubDir As String In aSubDirs
                If clsItem.Directory.ToLower = strSubDir.ToLower Then
                    blnRemove = False
                    Exit For
                End If
            Next
            If blnRemove Then
                aSharedItems.RemoveAt(i)
                tracker.RemoveChangedItem(clsItem)
                Using t As New DataStore.TransactionScope
                    DataStore.SharedItems.Delete(clsItem, t)
                    t.Complete()
                End Using
                Manager.OnSharedItemDeleted(clsItem)
            End If
        Next

        'now, create new missing items 
        For Each strSubDir As String In aSubDirs
            'Dim blnCreate As Boolean = True
            Dim clsExistingItem As Entities.SharedItem = Nothing
            For Each clsItem As Entities.SharedItem In aSharedItems
                If strSubDir.ToLower = clsItem.Directory.ToLower Then
                    'blnCreate = False
                    clsExistingItem = clsItem
                    Exit For
                End If
            Next
            If clsExistingItem Is Nothing Then
                Dim clsItem As New Entities.SharedItem
                clsItem.Added = Now.ToUniversalTime
                clsItem.Directory = strSubDir
                clsItem.GroupMode = tracker.Share.GroupMode
                clsItem.ItemType = tracker.Share.ItemTypes
                clsItem.LastChanged = Now
                clsItem.Name = IO.Path.GetFileName(strSubDir)
                clsItem.SourceWatchFolderId = tracker.Share.Id
                clsItem.UniqueId = Utils.Misc.GenerateUniqueId
                DataStore.SharedItems.Save(clsItem)

                Using t As New DataStore.TransactionScope
                    If UpdateFiles(tracker, clsItem, t) Then
                        Dim clsMI As Entities.MediaInfo = ScanFolder_Common.CreateMediaInfoEx(clsItem)
                        DataStore.SharedItems.Save(clsItem, t)
                        If clsMI IsNot Nothing Then
                            clsMI.SharedItemId = clsItem.Id
                            DataStore.MediaInfo.Save(clsMI, t)
                            clsItem.HasMediaInfo = True
                            DataStore.SharedItems.Save(clsItem, t)
                        End If
                        Manager.OnSharedItemCreated(clsItem)
                    End If

                End Using
            Else
                Using t As New DataStore.TransactionScope
                    If UpdateFiles(tracker, clsExistingItem, t) Then
                        Dim clsMI As Entities.MediaInfo = ScanFolder_Common.CreateMediaInfoEx(clsExistingItem)
                        DataStore.SharedItems.Save(clsExistingItem)
                        If clsMI IsNot Nothing Then
                            DataStore.MediaInfo.Save(clsMI, t)
                            clsExistingItem.HasMediaInfo = True
                            DataStore.SharedItems.Save(clsExistingItem, t)
                        End If
                        Manager.OnSharedItemUpdated(clsExistingItem)
                    End If

                End Using
            End If
        Next
    End Sub

    Private Shared Function UpdateFiles(ByVal tracker As ScanTracker, ByVal item As Entities.SharedItem, ByVal transactionScope As DataStore.TransactionScope) As Boolean
        Dim aFilesInfos As Generic.Dictionary(Of String, IO.FileInfo)
        aFilesInfos = ScanFolder_Common.GetAllFileInfosRecursive(item.Directory)

        Dim aFiles As Generic.List(Of Entities.SharedItemFile)
        aFiles = DataStore.SharedItemsFiles.GetAllBySharedItemId(item.Id)

        Dim blnChanged As Boolean = False

        Dim aSaved As New Generic.Dictionary(Of String, String)
        For Each clsFile As Entities.SharedItemFile In aFiles
            Dim strFileName As String = IO.Path.Combine(clsFile.Directory, clsFile.FileName).ToLower
            If aFilesInfos.ContainsKey(strFileName) Then
                aSaved.Add(strFileName, Nothing)
                Dim clsFI As IO.FileInfo = aFilesInfos(strFileName)
                blnChanged = blnChanged Or ScanFolder_Common.UpdateSharedFileIfChanged(clsFI, clsFile, transactionScope)
            Else
                DataStore.SharedItemsFiles.SetFileAsOrphan(clsFile, transactionScope)
                blnChanged = True
            End If
        Next
        Dim iTotalFiles As Short = 0
        Dim lTotalSize As Long = 0
        Dim dtLastChange As Date = Date.MinValue
        For Each clsFI As IO.FileInfo In aFilesInfos.Values
            iTotalFiles += CShort(1)
            lTotalSize += clsFI.Length
            If clsFI.LastWriteTimeUtc > dtLastChange Then dtLastChange = clsFI.LastWriteTimeUtc
            If Not aSaved.ContainsKey(clsFI.FullName.ToLower) Then
                Dim clsFile As Entities.SharedItemFile
                clsFile = ScanFolder_Common.CreateSharedItemFile(clsFI)
                clsFile.SharedItemId = item.Id
                DataStore.SharedItemsFiles.Save(clsFile, transactionScope)
                blnChanged = True
            End If
        Next
        If item.TotalFiles <> iTotalFiles Then
            blnChanged = True
            item.TotalFiles = iTotalFiles
        End If
        If item.TotalSize <> lTotalSize Then
            blnChanged = True
            item.TotalSize = lTotalSize
        End If
        If Math.Abs(dtLastChange.Subtract(item.LastChanged).TotalSeconds) > 1 Then
            blnChanged = True
            item.LastChanged = dtLastChange
        End If
        Return blnChanged
    End Function
End Class
